package com.example.base.ui.fragment

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.annotation.IntRange
import androidx.annotation.LayoutRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import com.example.base.broadcast.Event
import com.example.base.broadcast.EventBusUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import com.example.base.ext.LoadingView
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

/**  Fragment 的基类  **/
abstract class BaseFragment<VDB : ViewDataBinding> : Fragment(), CoroutineScope by MainScope(),
    LoadingView {

    /**  ViewDataBinding 对象  **/
    protected lateinit var mBinding: VDB
    fun ismBindingInitialised() = ::mBinding.isInitialized

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.apply {
            initParams(this)
        }
    }

    /**  初始化 Fragment 的初始数据时可重写该方法, 直接使用 arguments 参数即  **/
    protected open fun initParams(arguments: Bundle) {}

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        mBinding = DataBindingUtil.inflate(inflater, getContentRes(), container, false)
        return mBinding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        mBinding.lifecycleOwner = this
        initData(view, savedInstanceState)
    }

    override fun onDestroy() {
        super.onDestroy()
        if (EventBus.getDefault().isRegistered(this)) {//加上判断

            if (isRegisterEventBus()) {
                EventBusUtil.unregister(this);
            }
        }
        cancel()
        mBinding.unbind()
    }

    /**  初始化数据  **/
    protected open fun initData(view: View, savedInstanceState: Bundle?) {}

    /**  主布局的 ID **/
    @LayoutRes
    abstract fun getContentRes(): Int

    /**
     * 跳转 Activity 获取结果, 该请求的 onActivityResult 会调用父 Activity 的, 跳转结果处理请在父 Activity 中执行
     * @param requestCode 请求码
     */
    protected inline fun <reified T : Activity> startActivityForResult(requestCode: Int) =
        activity?.startActivityForResult(Intent(activity, T::class.java), requestCode)

    /**
     * 显示吐司
     * @param content 吐司显示的内容
     * @param duration 吐司显示的时长, 默认是 [Toast.LENGTH_LONG]
     */
    fun toast(
        content: String,
        @IntRange(
            from = Toast.LENGTH_SHORT.toLong(),
            to = Toast.LENGTH_LONG.toLong()
        ) duration: Int = Toast.LENGTH_LONG
    ) {
        requireActivity().runOnUiThread {
            Toast.makeText(activity, content, duration).show()
        }
    }
    /**
     * 是否注册事件分发
     *
     * @return true绑定EventBus事件分发，默认不绑定，子类需要绑定的话复写此方法返回true.
     */
    protected open fun isRegisterEventBus(): Boolean {
        return false
    }
    override fun showProgress() = (activity!! as LoadingView).showProgress()

    override fun hideProgress() = (activity!! as LoadingView).hideProgress()

    @Subscribe(threadMode = ThreadMode.MAIN)
    open fun onEventBusCome(event: Event<Any>?) {
        if (event != null) {
            receiveEvent(event)
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    open fun onStickyEventBusCome(event: Event<Any>?) {
        if (event != null) {
            receiveStickyEvent(event)
        }
    }

    /**
     * 接收到分发到事件
     *
     * @param event 事件
     */
    open fun receiveEvent(event: Event<Any>?) {}

    /**
     * 接受到分发的粘性事件
     *
     * @param event 粘性事件
     */
    open fun receiveStickyEvent(event: Event<Any>?) {}

    override fun onStart() {
        super.onStart()
        if (!EventBus.getDefault().isRegistered(this)) {//加上判断
            if (isRegisterEventBus()) {
                EventBusUtil.register(this);
            }
        }
    }



}